;****************************************************************************************************
; Line6Template 2012
;
; This file is the blank template for the course S-89.3510 DSP Processors and Audio Signal Processing
; taught at Aalto University. This template is based on the file Blank.asm
; downloaded from http://www.tcddk.com/.
;
; Modifyed by Jussi Pekonen, February 2009, Antti Pakarinen, February 2012
; 
;****************************************************************************************************
  
                page    132,60
                include "..\Ioequ.inc"
                include "..\vectors4.inc"                
                list
;**********************************************************************
; The following definition switches between a simulator version and
; a real-time version of the program. Set this to '1' if you are
; analyzing the program with the simulator, and to '0' if you are
; running the program in Line6 TCDDK.
; **********************************************************************
              	
              	define	simulator '0'

;**********************************************************************
; If you need to initialize constants, change the number of constants 
; here. Declare them them at the end of the code. 
;(Bug in the Line6, can't declare constants directly in X- or Y-memory.)
;**********************************************************************

N				equ 	1			
;**********************************************************
; X-memory allocations for hardware init -related functions
;**********************************************************
        org     x:$000
;
; Knob registers expect a value of 0x000000 thru 0x7FFFFF from the microcontroller
Knob_1                  ds  1       ; 00h
Knob_2                  ds  1       ; 01h
Knob_3                  ds  1       ; 02h
Knob_4                  ds  1       ; 03h
Knob_5                  ds  1       ; 04h
Knob_6                  ds  1       ; 05h

; Switch registers expect a value of 0,1, or 2 from the microcontroller
Switch_1                ds  1       ; 06h
Switch_2                ds  1       ; 07h

; FootSwitch registers expect a value of 0x000000 or 0x000001 from the microcontroller
FootSwitch_TopLayer     ds  1       ; 08h
FootSwitch_BottomLayer  ds  1       ; 09h

; LED registers are read by the micro and should be set to 0x000000 or 0x000001  (off and on)
LED_Red                 ds  1       ; 0ah
LED_Green               ds  1       ; 0bh

; RX and TX registers
LeftRx                  ds  1       ; 0ch   Left received sample
RightRx                 ds  1       ; 0dh   Right received sample
LeftTx                  ds  1       ; 0eh   Left sample to transmit
RightTx                 ds  1       ; 0fh   Right sample to transmit
SHI_StateMachine        ds  1       ; 10h   current state of the serial host interface
HostCommand             ds  1       ; 11h   current SHI command

; Debug registers
Debug_Write_to_DSP_1    ds  1       ; 12h   recieves data from the ToneCoreGUI application
Debug_Write_to_DSP_2    ds  1       ; 13h   recieves data from the ToneCoreGUI application
Debug_Write_to_DSP_3    ds  1       ; 14h   recieves data from the ToneCoreGUI application
Debug_Write_to_DSP_4    ds  1       ; 15h   recieves data from the ToneCoreGUI application
Debug_Read_from_DSP_1   ds  1       ; 16h   send data to the ToneCoreGUI application
Debug_Read_from_DSP_2   ds  1       ; 17h   send data to the ToneCoreGUI application
Debug_Read_from_DSP_3   ds  1       ; 18h   send data to the ToneCoreGUI application
Debug_Read_from_DSP_4   ds  1       ; 19h   send data to the ToneCoreGUI application

; Foot Latch states
FootLatch               ds  1       
FootLatchMem            ds  1       
;Hardware related initializations end--------------------------------

;*********************************************
; Own X-memory allocations
;*********************************************
		org		x:$040	

;**********************************************
; Y-memory allocations
;**********************************************
        org     y:$000
C:				ds	N

;***********************************************************************
; The main program starts here. First some HW-related initializations
;***********************************************************************
        org     p:$4E
START
        ori     #$03,mr                 ; mask interrupts
        movep   #$2D0063,X:M_PCTL       ; Set PLL Control Register: Fosc = 100 MHz = (100)(3 MHz)/3
        bset    #14,omr                 ; allow address attributes line to function independently
        movep   #>$000040,x:M_SAICR     ; 4x4 Synchronous mode (use TX frame and bit clks)
        movep   #$FCC304,x:M_TCCR                           
        movep  	#$FCC304,x:M_RCCR                          
        movep   #$707d00,x:M_RCR                            
        movep   #$027D80,x:M_TCR                            
        movep   #>$000000,x:M_PDRC      ; Clear Port C data
        movep   #>$000BF8,x:M_PCRC      ; Set appropriate Port C GPIO pins for ESAI .
        movep   #>$000C7E,x:M_PRRC      ; Set pin direction of PORT C
        movep   #>$000000,x:M_PCRB      ; Set up Port B for output
        movep   #>$00000F,x:M_PRRB      ; Set up Port B for output
        movep   #>$000008,x:M_PDRB      ; bit 0 = In_EMPH, bit 1 = OUT_DE_EMPH, bit 2 = DIRECT_ON, bit 3 = FX_ON
        movep   #>$000003,x:M_RSMA      ; Enable first 2 time slots for receive.
        movep   #>$000000,x:M_RSMB      ;
        movep   #>$000003,x:M_TSMA      ; Enable first 2 time slots for transmit.
        movep   #>$000000,x:M_TSMB      
        movep   #>$000000,x:M_TX0       ; zero out transmitter 0
        ; ENABLE ESAI
        bset    #0,x:M_RCR              ; now enable RX0
        bset    #0,x:M_TCR              ; now enable TX0
		; Setup Expansion Port A for SRAM...
        movep   #$2406B5,x:M_AAR0                
        movep   #$2003B1,x:M_AAR1
		; Bus Control Register for SRAM...
        movep   #$0124A5,x:M_BCR        ;        0001 0010 0100 0110 0011
		; Set up SHI (Serial Host Interface to the MCU)...
        movep   #>$003001,x:M_HCKR      ; Turn Data/Clk Line Filter to max, wide spike tolerance (100ns glitch)
        movep   #>$001189,x:M_HCSR      ; CPHA=1, CPOL=0 : => same as reset/power-on.
		; Initialize registers
        move    #>$000000,x0
        move    x0,r0
        rep     #28 
        move    x0,x:(r0)+              ; clear start of x:mem
        move    #>$400000,x0			; Intialize the knob registers
        move    x0,x:Knob_1     
        move    x0,x:Knob_2     
        move    x0,x:Knob_3     
        move    x0,x:Knob_4     
        move    x0,x:Knob_5     
        move    x0,x:Knob_6     
        move    #>$000000,x0
        move    #$00ffff,m5             ; Use r5 for the MCU parameter updates.
        movep   x0,x:M_HTX              ; Assert HREQ* pin for the MCU.
		; Initialize Peripheral Interrupt Priority Register for Audio Interrupts and SHI.
        movep   #$000007,x:M_IPRP       ; ESAI int's enabled and top Priority, SHI int's enabled and lowest Priority.
        andi    #$FC,mr                 ;enable all interrupt levels
        movep   #>$000002,x:M_PDRC      ; Take CODEC out of power down mode.
        
        move 	#$00ffff,m0
        move 	#$00ffff,m2
        move 	#$00ffff,m3
		move 	#$00ffff,m4
		
		move 	#0,x0
	   ;Move constants from P- to Y-memory (Line6 bug, can't define constants directly in X- or Y-memory
        move 	#Constants,r0       	; address in program memory
		move 	#C,r4   				; address in Y memory
		do #N,init_constants_end 		; repeat for number of entries
			move p:(r0)+,y0 
			move y0,y:(r4)+
init_constants_end
;*******************************************
; Own initializations
;*******************************************

						
;------------------------------------------------------------
; Main loop. Program waits for interruptions here
;------------------------------------------------------------
LOOP
        
	if simulator
        jsr esai_rxeven_isr		;Force jump to subroutine in the simulator
	endif
        
    if !simulator
        wait
		; Waiting for interruptions from ESAI and SHI
	endif
        jmp     LOOP       
                           
;**************************************************************************
; Host Interrupt routines
;**************************************************************************
shi_receive
        movep   x:M_HRX,x:HostCommand	; Get word from 8031.
        movep   #000000,x:M_HTX			; Assert HREQ* pin for 8031.
        btst    #0,x:HostCommand        ; $000001 = Write 1 DSP word to X:mem.
        bcs     DoWriteCommand          ;
        btst    #3,x:HostCommand        ; $000008 = Send word to the 8031.
        bcs     DoReadCommand           ;
DoWriteCommand
        jclr    #M_HRNE,x:M_HCSR,*      ; Wait for address.
        movep   x:M_HRX,r5              ; Store address to write to.
        movep   #>000000,x:M_HTX        ; Assert HREQ* pin for 8031.
        jclr    #M_HRNE,x:M_HCSR,*      ; Wait for data 
        movep   x:M_HRX,x:(r5)          ; Write data.
        movep   #000000,x:M_HTX         ; Assert HREQ* pin for 8031.
		rti
DoReadCommand
        jclr    #M_HRNE,x:M_HCSR,*
        movep   x:M_HRX,r5              ; Store Address to read from
        movep   #>000000,x:M_HTX
        jclr    #M_HRNE,x:M_HCSR,*
        movep   x:M_HRX,n5                
        movep   x:(r5),x:<<M_HTX        ; Send Data at specified address to the 8031
        jclr    #M_HRNE,x:M_HCSR,*
        movep   x:M_HRX,n5
        movep   #>000000,x:<<M_HTX
		rti

;*********************
; Receive Interrupts.
;********************
;----------------------------
; Receive Exception Interrupt
;----------------------------
esai_rxe_isr                            ; ESAI RECEIVE ISR
        bclr    #7,x:M_SAISR            ; Read SAISR to clear receive, overrun error flag
        bclr    #14,x:M_SAISR           ; Read SAISR to clear transmit, underrun error flag
        movep   x:M_RX0,x:RightRx       ; 
        movep   x:RightTx,x:M_TX0       ;
        rti

;------------------
; Receive Interrupt
;------------------
esai_rx_isr
        movep   x:M_RX0,x:RightRx       
        movep   x:RightTx,x:M_TX0       
        rti

;----------------------------
; Receive Even Slot Interrupt
;----------------------------
esai_rxeven_isr
        if !simulator
        movep   x:M_RX0,x:LeftRx        
        movep   x:LeftTx,x:M_TX0
        endif
		 ; The left channel sample to be processed     
        move    x:LeftRx,x0
        ; The right channel sample to be processed
        move    x:RightRx,x1

		;*****************************************************************************************
		; Do the processing here! x0 contains the left channel sample, x1 the right channel sample
		;*****************************************************************************************
		
		
		;*****************************************************************************************
		; Output routines
		;*****************************************************************************************
		; The left channel sample to be outputted
		move	x0,x:LeftTx
		; The right channel sample to be outputted
		move	x1,x:RightTx
	
  		move    x:FootSwitch_TopLayer,a      ; load unmodified footswitch input
        move    x:FootSwitch_TopLayer,x1     ; load unmodified footswitch input 
        not     a       x:FootLatchMem,x0       ; not a  (also, load the previous momentary signal into x0)
        and     x0,a    x1,x:FootLatchMem       ; x0 & a (also, store current momentary signal for next iteration)
        move    x:FootLatch,x0                  ; load previous latched value
        eor     x0,a                            ; generate current latched (step) control signal
        move    a1,x:FootLatch                  ; store latched footswitch signal created from momentary footswitch
        move    x:FootLatch,a           ; load latching footswitch signal
        jclr    #0,a,ANALOG_BYPASS      ; bit clear = bypass
        movep   #>$000008,x:M_PDRB      ; bit 3 on  = FX_ON
        bset    #0,x:LED_Green          ; turn led on to indicate effect on
        jmp     END_ANALOG_BYPASS
ANALOG_BYPASS:            
        movep   #>$000004,x:M_PDRB      ; bit 2 on  = DIRECT_ON
        bclr    #0,x:LED_Green          ; turn led off to indicate effect off
END_ANALOG_BYPASS:
        rti                             ; return from interrupt

	
	;Section of program memory to be used to define constants
	section P_DATA_MEMORY global
		org 	p:
Constants:
	;************************************************************************************
	;Define your constants here. At initialization, they will be transferred
	;to the start of Y-memory, labeled "C". Type the number of the constants in line 37
	;Be aware that if the constants don't fit in P-memory, they will get truncated
	;without warning. If you have problems, check that all the constant have been copied
	;to Y-memory at initialization
	;************************************************************************************
		dc	0	;dummy value	
	
	endsec
